//+------------------------------------------------------------------+
//|                    Chart.mqh MQL5 图表管理核心类头文件            |
//|                版权所有 2000-2025, MetaQuotes Ltd.              |
//|                        官方网址: https://www.mql5.com            |
//+------------------------------------------------------------------+
//| 包含 MQL5 图表管理核心类 CChart，封装图表的创建、配置、交互、指标管理等全功能 |
//+------------------------------------------------------------------+
#include <Object.h>  // 引入 MQL5 基础对象类 CObject（提供对象生命周期管理）

//+------------------------------------------------------------------+
//| CChart 类（图表管理核心类）                                      |
//| 功能：MQL5 平台图表的全方位管理工具，支持图表创建、属性配置、外观定制、指标操作、事件监听等 |
//| 继承关系：public CObject（基于 MQL5 基础对象类，具备对象通用特性）   |
//| 核心能力模块：                                                  |
//|  1. 图表生命周期管理：创建、绑定、关闭、切换图表                  |
//|  2. 基础属性配置：显示模式（K线/蜡烛图）、缩放、滚动、坐标轴控制     |
//|  3. 外观定制：颜色（背景/蜡烛/网格等）、显示元素（成交量/买卖线等）开关 |
//|  4. 只读信息获取：可见K线数、窗口尺寸、价格范围等运行时信息         |
//|  5. 交互与事件：鼠标滚动、对象创建/删除事件监听、图表导航           |
//|  6. 指标管理：添加、删除、查询图表中的技术指标                     |
//|  7. 底层API封装：直接调用 MQL5 图表底层函数，支持扩展配置           |
//|  8. 序列化：图表配置的保存与加载（如模板参数）                     |
//+------------------------------------------------------------------+
class CChart : public CObject
  {
protected:
   long              m_chart_id;  // 图表唯一标识（核心成员，所有图表操作的基础）

public:
   /**
    * @brief 构造函数：初始化图表管理对象
    * @details 初始化图表ID为 -1（表示未绑定任何图表），需通过 Attach/Open 方法绑定或创建图表
    */
                     CChart(void);

   /**
    * @brief 析构函数：销毁图表管理对象
    * @details 自动关闭已绑定的图表（若图表ID有效），释放资源，避免内存泄漏
    */
                    ~CChart(void);

   //================================================================
   // 模块1：图表生命周期与绑定管理（核心基础功能）
   //================================================================
   /**
    * @brief 获取当前绑定的图表ID
    * @return long - 图表ID（-1 表示未绑定图表，0 表示当前活跃图表，>0 表示指定图表）
    */
   long              ChartId(void) const { return(m_chart_id); }

   /**
    * @brief 绑定到当前活跃图表（即当前前台显示的图表）
    * @details 将对象与 MQL5 平台当前激活的图表关联，后续操作针对该图表
    */
   void              Attach(void) { m_chart_id=ChartID(); }

   /**
    * @brief 绑定到指定ID的图表
    * @param chart [in] 目标图表ID（可通过 ChartFirst()/ChartNext() 遍历获取所有图表ID）
    */
   void              Attach(const long chart) { m_chart_id=chart; }

   /**
    * @brief 切换到第一个已打开的图表
    * @details 常用于遍历所有图表场景，调用后 m_chart_id 设为第一个图表ID
    */
   void              FirstChart(void) { m_chart_id=ChartFirst(); }

   /**
    * @brief 切换到下一个已打开的图表
    * @details 配合 FirstChart() 实现所有图表的遍历（如批量配置多个图表属性）
    */
   void              NextChart(void) { m_chart_id=ChartNext(m_chart_id); }

   /**
    * @brief 创建新图表并绑定
    * @param symbol_name [in] 图表对应的交易品种（如 "EURUSD"、"XAUUSD"）
    * @param timeframe [in] 图表时间周期（MQL5 预定义枚举，如 PERIOD_M1=1分钟，PERIOD_H1=1小时）
    * @return long - 新创建图表的ID（0 表示创建失败，需检查品种/周期是否有效）
    */
   long              Open(const string symbol_name,const ENUM_TIMEFRAMES timeframe);

   /**
    * @brief 解除与当前图表的绑定（不关闭图表）
    * @details 将 m_chart_id 设为 -1，后续操作需重新绑定图表
    */
   void              Detach(void) { m_chart_id=-1; }

   /**
    * @brief 关闭当前绑定的图表
    * @details 调用 MQL5 底层 ChartClose 函数，关闭图表并释放相关资源，之后 m_chart_id 设为 -1
    */
   void              Close(void);

   //================================================================
   // 模块2：图表基础属性配置（显示模式、缩放、滚动等核心控制）
   //================================================================
   /**
    * @brief 获取图表当前的显示模式（K线类型）
    * @return ENUM_CHART_MODE - 显示模式枚举值（如 CHART_BARS=柱状图，CHART_CANDLES=蜡烛图，CHART_LINE=折线图）
    */
   ENUM_CHART_MODE   Mode(void) const;

   /**
    * @brief 设置图表的显示模式（切换K线类型）
    * @param mode [in] 目标显示模式（需为 ENUM_CHART_MODE 枚举值）
    * @return bool - 操作结果：true 表示设置成功，false 表示失败（未绑定图表或模式无效）
    */
   bool              Mode(const ENUM_CHART_MODE mode) const;

   /**
    * @brief 获取图表是否置顶显示
    * @return bool - 状态值：true=图表置顶（始终显示在其他窗口上方），false=不置顶
    */
   bool              Foreground(void) const;

   /**
    * @brief 设置图表是否置顶显示
    * @param foreground [in] 目标状态（true=置顶，false=不置顶）
    * @return bool - 操作结果：true 表示设置成功，false 表示失败（未绑定图表）
    */
   bool              Foreground(const bool foreground) const;

   /**
    * @brief 获取图表是否启用水平偏移（右侧预留空白区域）
    * @return bool - 状态值：true=启用偏移（K线不贴紧右侧，预留空白用于显示新K线），false=禁用
    */
   bool              Shift(void) const;

   /**
    * @brief 设置图表是否启用水平偏移
    * @param shift [in] 目标状态（true=启用，false=禁用）
    * @return bool - 操作结果：true 表示设置成功，false 表示失败（未绑定图表）
    */
   bool              Shift(const bool shift) const;

   /**
    * @brief 获取水平偏移的空白区域大小（像素）
    * @return double - 偏移大小（像素，范围 10~50，值越大空白区域越宽）
    */
   double            ShiftSize(void) const;

   /**
    * @brief 设置水平偏移的空白区域大小
    * @param shift [in] 目标偏移大小（像素，自动限制在 10~50 范围内，超出则取边界值）
    * @return bool - 操作结果：true 表示设置成功，false 表示失败（未绑定图表）
    */
   bool              ShiftSize(double shift) const;

   /**
    * @brief 获取图表是否启用自动滚动
    * @return bool - 状态值：true=自动滚动（新K线生成时自动滚动到最右侧），false=手动滚动
    */
   bool              AutoScroll(void) const;

   /**
    * @brief 设置图表是否启用自动滚动
    * @param auto_scroll [in] 目标状态（true=自动滚动，false=手动滚动）
    * @return bool - 操作结果：true 表示设置成功，false 表示失败（未绑定图表）
    */
   bool              AutoScroll(const bool auto_scroll) const;

   /**
    * @brief 获取图表当前的缩放比例（控制K线显示密度）
    * @return int - 缩放比例（范围 0~32，0=最小缩放，32=最大缩放，值越大K线越密集）
    */
   int               Scale(void) const;

   /**
    * @brief 设置图表的缩放比例
    * @param scale [in] 目标缩放比例（自动限制在 0~32 范围内，超出则取边界值）
    * @return bool - 操作结果：true 表示设置成功，false 表示失败（未绑定图表）
    */
   bool              Scale(int scale) const;

   /**
    * @brief 获取图表是否启用固定缩放（价格轴不随K线波动自动调整）
    * @return bool - 状态值：true=固定缩放（价格轴范围手动设置，不自动变化），false=自动缩放
    */
   bool              ScaleFix(void) const;

   /**
    * @brief 设置图表是否启用固定缩放
    * @param scale_fix [in] 目标状态（true=固定缩放，false=自动缩放）
    * @return bool - 操作结果：true 表示设置成功，false 表示失败（未绑定图表）
    * @note 启用固定缩放后，需通过 FixedMax/FixedMin 手动设置价格轴范围
    */
   bool              ScaleFix(const bool scale_fix) const;

   /**
    * @brief 获取图表是否启用“时间-价格等同”缩放（江恩理论核心缩放模式）
    * @return bool - 状态值：true=启用（1单位时间对应1单位价格变动，K线角度反映趋势强度），false=禁用
    */
   bool              ScaleFix_11(void) const;

   /**
    * @brief 设置图表是否启用“时间-价格等同”缩放
    * @param scale_fix_11 [in] 目标状态（true=启用，false=禁用）
    * @return bool - 操作结果：true 表示设置成功，false 表示失败（未绑定图表）
    * @note 适用于江恩线、角度趋势线等基于时间价格比例的技术分析工具
    */
   bool              ScaleFix_11(const bool scale_fix_11) const;

   /**
    * @brief 获取固定缩放模式下价格轴的最大值
    * @return double - 价格轴最大值（仅在 ScaleFix=true 时有效，否则返回 EMPTY_VALUE）
    */
   double            FixedMax(void) const;

   /**
    * @brief 设置固定缩放模式下价格轴的最大值
    * @param fixed_max [in] 目标最大值（需大于 FixedMin，否则设置无效）
    * @return bool - 操作结果：true 表示设置成功，false 表示失败（未绑定图表或 ScaleFix=false）
    */
   bool              FixedMax(const double fixed_max) const;

   /**
    * @brief 获取固定缩放模式下价格轴的最小值
    * @return double - 价格轴最小值（仅在 ScaleFix=true 时有效，否则返回 EMPTY_VALUE）
    */
   double            FixedMin(void) const;

   /**
    * @brief 设置固定缩放模式下价格轴的最小值
    * @param fixed_min [in] 目标最小值（需小于 FixedMax，否则设置无效）
    * @return bool - 操作结果：true 表示设置成功，false 表示失败（未绑定图表或 ScaleFix=false）
    */
   bool              FixedMin(const double fixed_min) const;

   /**
    * @brief 获取图表是否按“每根K线点数”缩放（基于价格波动的自适应缩放）
    * @return bool - 状态值：true=启用（按每根K线的价格波动点数调整缩放），false=禁用
    */
   bool              ScalePPB(void) const;

   /**
    * @brief 设置图表是否按“每根K线点数”缩放
    * @param scale_ppb [in] 目标状态（true=启用，false=禁用）
    * @return bool - 操作结果：true 表示设置成功，false 表示失败（未绑定图表）
    */
   bool              ScalePPB(const bool scale_ppb) const;

   /**
    * @brief 获取“每根K线点数”参数（缩放计算的基础单位）
    * @return double - 每根K线对应的价格点数（如 0.001 表示每根K线按 10 个点差缩放）
    */
   double            PointsPerBar(void) const;

   /**
    * @brief 设置“每根K线点数”参数
    * @param points_per_bar [in] 目标点数（需大于 0，否则设置无效）
    * @return bool - 操作结果：true 表示设置成功，false 表示失败（未绑定图表）
    */
   bool              PointsPerBar(const double points_per_bar) const;

   //================================================================
   // 模块3：图表外观与显示元素控制（颜色、开关、成交量等）
   //================================================================
   /**
    * @brief 获取图表是否显示 OHLC 价格标签（K线顶部/底部显示开盘/最高/最低/收盘价）
    * @return bool - 状态值：true=显示，false=隐藏
    */
   bool              ShowOHLC(void) const;

   /**
    * @brief 设置图表是否显示 OHLC 价格标签
    * @param show [in] 目标状态（true=显示，false=隐藏）
    * @return bool - 操作结果：true 表示设置成功，false 表示失败（未绑定图表）
    */
   bool              ShowOHLC(const bool show) const;

   /**
    * @brief 获取图表是否显示买价线（Bid 线，当前可卖出价格对应的水平线）
    * @return bool - 状态值：true=显示，false=隐藏
    */
   bool              ShowLineBid(void) const;

   /**
    * @brief 设置图表是否显示买价线
    * @param show [in] 目标状态（true=显示，false=隐藏）
    * @return bool - 操作结果：true 表示设置成功，false 表示失败（未绑定图表）
    */
   bool              ShowLineBid(const bool show) const;

   /**
    * @brief 获取图表是否显示卖价线（Ask 线，当前可买入价格对应的水平线）
    * @return bool - 状态值：true=显示，false=隐藏
    */
   bool              ShowLineAsk(void) const;

   /**
    * @brief 设置图表是否显示卖价线
    * @param show [in] 目标状态（true=显示，false=隐藏）
    * @return bool - 操作结果：true 表示设置成功，false 表示失败（未绑定图表）
    */
   bool              ShowLineAsk(const bool show) const;

   /**
    * @brief 获取图表是否显示最新价线（Last 线，最新成交价格对应的水平线）
    * @return bool - 状态值：true=显示，false=隐藏
    */
   bool              ShowLastLine(void) const;

   /**
    * @brief 设置图表是否显示最新价线
    * @param show [in] 目标状态（true=显示，false=隐藏）
    * @return bool - 操作结果：true 表示设置成功，false 表示失败（未绑定图表）
    */
   bool              ShowLastLine(const bool show) const;

   /**
    * @brief 获取图表是否显示周期分隔线（不同时间周期的K线之间显示分隔线）
    * @return bool - 状态值：true=显示（如日线与周线之间显示竖线分隔），false=隐藏
    */
   bool              ShowPeriodSep(void) const;

   /**
    * @brief 设置图表是否显示周期分隔线
    * @param show [in] 目标状态（true=显示，false=隐藏）
    * @return bool - 操作结果：true 表示设置成功，false 表示失败（未绑定图表）
    */
   bool              ShowPeriodSep(const bool show) const;

   /**
    * @brief 获取图表是否显示网格线（时间轴与价格轴的交叉网格）
    * @return bool - 状态值：true=显示，false=隐藏
    */
   bool              ShowGrid(void) const;

   /**
    * @brief 设置图表是否显示网格线
    * @param show [in] 目标状态（true=显示，false=隐藏）
    * @return bool - 操作结果：true 表示设置成功，false 表示失败（未绑定图表）
    */
   bool              ShowGrid(const bool show) const;

   /**
    * @brief 获取图表成交量的显示模式
    * @return ENUM_CHART_VOLUME_MODE - 成交量模式枚举值（如 VOLUME_TICK= tick 成交量，VOLUME_REAL=实际成交量）
    */
   ENUM_CHART_VOLUME_MODE ShowVolumes(void) const;

   /**
    * @brief 设置图表成交量的显示模式
    * @param show [in] 目标模式（需为 ENUM_CHART_VOLUME_MODE 枚举值）
    * @return bool - 操作结果：true 表示设置成功，false 表示失败（未绑定图表）
    */
   bool              ShowVolumes(const ENUM_CHART_VOLUME_MODE show) const;

   /**
    * @brief 获取图表是否显示对象描述（鼠标悬停在图表对象上时显示名称/参数）
    * @return bool - 状态值：true=显示，false=隐藏
    */
   bool              ShowObjectDescr(void) const;

   /**
    * @brief 设置图表是否显示对象描述
    * @param show [in] 目标状态（true=显示，false=隐藏）
    * @return bool - 操作结果：true 表示设置成功，false 表示失败（未绑定图表）
    */
   bool              ShowObjectDescr(const bool show) const;

   /**
    * @brief 设置图表是否显示时间轴（X轴，底部的时间刻度）
    * @param show [in] 目标状态（true=显示，false=隐藏）
    * @return bool - 操作结果：true 表示设置成功，false 表示失败（未绑定图表）
    */
   bool              ShowDateScale(const bool show) const;

   /**
    * @brief 设置图表是否显示价格轴（Y轴，右侧的价格刻度）
    * @param show [in] 目标状态（true=显示，false=隐藏）
    * @return bool - 操作结果：true 表示设置成功，false 表示失败（未绑定图表）
    */
   bool              ShowPriceScale(const bool show) const;

   //------------------------------
   // 子模块3.1：图表颜色配置（外观定制核心）
   //------------------------------
   /**
    * @brief 获取图表背景颜色
    * @return color - 背景颜色（如 clrBlack=黑色，clrWhite=白色，支持自定义 RGB 颜色）
    */
   color             ColorBackground(void) const;

   /**
    * @brief 设置图表背景颜色
    * @param new_color [in] 目标颜色（MQL5 预定义颜色或自定义颜色，如 clr(R, G, B)）
    * @return bool - 操作结果：true 表示设置成功，false 表示失败（未绑定图表）
    */
   bool              ColorBackground(const color new_color) const;

   /**
    * @brief 获取图表前景色（文本、刻度等元素的颜色）
    * @return color - 前景色
    */
   color             ColorForeground(void) const;

   /**
    * @brief 设置图表前景色
    * @param new_color [in] 目标颜色
    * @return bool - 操作结果：true 表示设置成功，false 表示失败（未绑定图表）
    */
   bool              ColorForeground(const color new_color) const;

   /**
    * @brief 获取网格线颜色
    * @return color - 网格线颜色
    */
   color             ColorGrid(void) const;

   /**
    * @brief 设置网格线颜色
    * @param new_color [in] 目标颜色
    * @return bool - 操作结果：true 表示设置成功，false 表示失败（未绑定图表）
    */
   bool              ColorGrid(const color new_color) const;

   /**
    * @brief 获取上涨K线（柱状图）的颜色
    * @return color - 上涨K线颜色（仅在 Mode=CHART_BARS 时有效）
    */
   color             ColorBarUp(void) const;

   /**
    * @brief 设置上涨K线（柱状图）的颜色
    * @param new_color [in] 目标颜色
    * @return bool - 操作结果：true 表示设置成功，false 表示失败（未绑定图表）
    */
   bool              ColorBarUp(const color new_color) const;

   /**
    * @brief 获取下跌K线（柱状图）的颜色
    * @return color - 下跌K线颜色（仅在 Mode=CHART_BARS 时有效）
    */
   color             ColorBarDown(void) const;

   /**
    * @brief 设置下跌K线（柱状图）的颜色
    * @param new_color [in] 目标颜色
    * @return bool - 操作结果：true 表示设置成功，false 表示失败（未绑定图表）
    */
   bool              ColorBarDown(const color new_color) const;

   /**
    * @brief 获取阳线蜡烛图的颜色（收盘价 > 开盘价）
    * @return color - 阳线颜色（仅在 Mode=CHART_CANDLES 时有效）
    */
   color             ColorCandleBull(void) const;

   /**
    * @brief 设置阳线蜡烛图的颜色
    * @param new_color [in] 目标颜色（通常设为绿色系，如 clrGreen）
    * @return bool - 操作结果：true 表示设置成功，false 表示失败（未绑定图表）
    */
   bool              ColorCandleBull(const color new_color) const;

   /**
    * @brief 获取阴线蜡烛图的颜色（收盘价 < 开盘价）
    * @return color - 阴线颜色（仅在 Mode=CHART_CANDLES 时有效）
    */
   color             ColorCandleBear(void) const;

   /**
    * @brief 设置阴线蜡烛图的颜色
    * @param new_color [in] 目标颜色（通常设为红色系，如 clrRed）
    * @return bool - 操作结果：true 表示设置成功，false 表示失败（未绑定图表）
    */
   bool              ColorCandleBear(const color new_color) const;

   /**
    * @brief 获取折线图（价格线）的颜色
    * @return color - 折线图颜色（仅在 Mode=CHART_LINE 时有效）
    */
   color             ColorChartLine(void) const;

   /**
    * @brief 设置折线图（价格线）的颜色
    * @param new_color [in] 目标颜色
    * @return bool - 操作结果：true 表示设置成功，false 表示失败（未绑定图表）
    */
   bool              ColorChartLine(const color new_color) const;

   /**
    * @brief 获取成交量柱子的颜色
    * @return color - 成交量颜色（仅在 ShowVolumes 启用时有效）
    */
   color             ColorVolumes(void) const;

   /**
    * @brief 设置成交量柱子的颜色
    * @param new_color [in] 目标颜色
    * @return bool - 操作结果：true 表示设置成功，false 表示失败（未绑定图表）
    */
   bool              ColorVolumes(const color new_color) const;

   /**
    * @brief 获取买价线（Bid 线）的颜色
    * @return color - 买价线颜色（仅在 ShowLineBid=true 时有效）
    */
   color             ColorLineBid(void) const;

   /**
    * @brief 设置买价线（Bid 线）的颜色
    * @param new_color [in] 目标颜色（通常设为蓝色系，如 clrBlue）
    * @return bool - 操作结果：true 表示设置成功，false 表示失败（未绑定图表）
    */
   bool              ColorLineBid(const color new_color) const;

   /**
    * @brief 获取卖价线（Ask 线）的颜色
    * @return color - 卖价线颜色（仅在 ShowLineAsk=true 时有效）
    */
   color             ColorLineAsk(void) const;

   /**
    * @brief 设置卖价线（Ask 线）的颜色
    * @param new_color [in] 目标颜色（通常设为橙色系，如 clrOrange）
    * @return bool - 操作结果：true 表示设置成功，false 表示失败（未绑定图表）
    */
   bool              ColorLineAsk(const color new_color) const;

   /**
    * @brief 获取最新价线（Last 线）的颜色
    * @return color - 最新价线颜色（仅在 ShowLastLine=true 时有效）
    */
   color             ColorLineLast(void) const;

   /**
    * @brief 设置最新价线（Last 线）的颜色
    * @param new_color [in] 目标颜色（通常设为紫色系，如 clrPurple）
    * @return bool - 操作结果：true 表示设置成功，false 表示失败（未绑定图表）
    */
   bool              ColorLineLast(const color new_color) const;

   /**
    * @brief 获取止损/止盈价位线的颜色
    * @return color - 止损止盈线颜色（图表上显示的订单止损/止盈标记线颜色）
    */
   color             ColorStopLevels(void) const;

   /**
    * @brief 设置止损/止盈价位线的颜色
    * @param new_color [in] 目标颜色（通常设为红色系表示止损，绿色系表示止盈）
    * @return bool - 操作结果：true 表示设置成功，false 表示失败（未绑定图表）
    */
   bool              ColorStopLevels(const color new_color) const;

   //================================================================
   // 模块4：图表交互与事件控制（鼠标操作、事件监听等）
   //================================================================
   /**
    * @brief 将当前绑定的图表置顶显示（强制显示在所有窗口最上层）
    * @return bool - 操作结果：true 表示设置成功，false 表示失败（未绑定图表）
    */
   bool              BringToTop(void) const;

   /**
    * @brief 启用/禁用“图表对象创建”事件监听
    * @param flag [in] 监听状态（true=启用，图表创建对象时触发 OnChartEvent 事件；false=禁用）
    * @return bool - 操作结果：true 表示设置成功，false 表示失败（未绑定图表）
    */
   bool              EventObjectCreate(const bool flag=true) const;

   /**
    * @brief 启用/禁用“图表对象删除”事件监听
    * @param flag [in] 监听状态（true=启用，图表删除对象时触发 OnChartEvent 事件；false=禁用）
    * @return bool - 操作结果：true 表示设置成功，false 表示失败（未绑定图表）
    */
   bool              EventObjectDelete(const bool flag=true) const;

   /**
    * @brief 启用/禁用“鼠标移动”事件监听
    * @param flag [in] 监听状态（true=启用，鼠标在图表上移动时触发 OnChartEvent 事件；false=禁用）
    * @return bool - 操作结果：true 表示设置成功，false 表示失败（未绑定图表）
    */
   bool              EventMouseMove(const bool flag=true) const;

   /**
    * @brief 启用/禁用“鼠标滚动”控制图表缩放
    * @param flag [in] 控制状态（true=启用，鼠标滚轮可缩放图表；false=禁用）
    * @return bool - 操作结果：true 表示设置成功，false 表示失败（未绑定图表）
    */
   bool              MouseScroll(const bool flag=true) const;

   /**
    * @brief 图表导航（快速定位到指定位置）
    * @param position [in] 目标位置（ENUM_CHART_POSITION 枚举值，如 CHART_POSITION_BEGIN=图表开始，CHART_POSITION_END=图表末尾）
    * @param shift [in] 偏移量（基于目标位置的额外偏移，如 position=CHART_POSITION_END 时，shift=10 表示定位到末尾前10根K线）
    * @return bool - 操作结果：true 表示导航成功，false 表示失败（未绑定图表或位置无效）
    */
   bool              Navigate(const ENUM_CHART_POSITION position,const int shift=0) const;

   //================================================================
   // 模块5：图表只读信息获取（运行时状态与数据）
   //================================================================
   /**
    * @brief 获取图表当前可见的K线数量
    * @return int - 可见K线数（0 表示未绑定图表或获取失败）
    * @note 常用于指标计算时确定数据范围（如仅计算可见K线的指标值）
    */
   int               VisibleBars(void) const;

   /**
    * @brief 获取图表包含的子窗口总数（主窗口+指标子窗口）
    * @return int - 子窗口总数（0 表示未绑定图表，≥1 表示有效，主窗口为 0 号，指标子窗口从 1 开始编号）
    */
   int               WindowsTotal(void) const;

   /**
    * @brief 检查指定子窗口是否可见
    * @param num [in] 子窗口编号（0=主窗口，≥1=指标子窗口）
    * @return bool - 可见状态：true=窗口可见，false=窗口隐藏或编号无效
    */
   bool              WindowIsVisible(const int num) const;

   /**
    * @brief 获取图表窗口的系统句柄（底层窗口标识，用于系统级操作）
    * @return int - 窗口句柄（INVALID_HANDLE 表示未绑定图表或获取失败）
    */
   int               WindowHandle(void) const;

   /**
    * @brief 获取图表上第一个可见K线的索引（相对于图表所有K线的索引）
    * @return int - 第一个可见K线索引（-1 表示未绑定图表或获取失败）
    * @note 图表K线索引从 0 开始（最早的K线），值越大越靠近当前时间
    */
   int               FirstVisibleBar(void) const;

   /**
    * @brief 获取图表在水平方向上可显示的K线数量（与图表宽度和缩放比例相关）
    * @return int - 水平可显示K线数（0 表示未绑定图表）
    */
   int               WidthInBars(void) const;

   /**
    * @brief 获取图表窗口的宽度（像素）
    * @return int - 窗口宽度（像素，0 表示未绑定图表）
    */
   int               WidthInPixels(void) const;

   /**
    * @brief 获取指定子窗口的高度（像素）
    * @param num [in] 子窗口编号（0=主窗口，≥1=指标子窗口）
    * @return int - 窗口高度（像素，0 表示未绑定图表或编号无效）
    */
   int               HeightInPixels(const int num) const;

   /**
    * @brief 获取指定子窗口相对于图表顶部的垂直偏移（像素）
    * @param num [in] 子窗口编号（0=主窗口，≥1=指标子窗口）
    * @return int - 垂直偏移（像素，0 表示未绑定图表或编号无效）
    */
   int               SubwindowY(const int num) const;

   /**
    * @brief 获取指定子窗口当前显示的最低价格
    * @param num [in] 子窗口编号（0=主窗口，≥1=指标子窗口）
    * @return double - 最低价格（EMPTY_VALUE 表示未绑定图表或编号无效）
    */
   double            PriceMin(const int num) const;

   /**
    * @brief 获取指定子窗口当前显示的最高价格
    * @param num [in] 子窗口编号（0=主窗口，≥1=指标子窗口）
    * @return double - 最高价格（EMPTY_VALUE 表示未绑定图表或编号无效）
    */
   double            PriceMax(const int num) const;

   /**
    * @brief 检查当前绑定的图表是否为“对象模式”（嵌入到其他窗口的子图表）
    * @return bool - 模式状态：true=对象模式（子图表），false=独立窗口模式（普通图表）
    */
   bool              IsObject(void) const;

   //================================================================
   // 模块6：图表底层API封装（直接调用 MQL5 底层函数，支持扩展配置）
   //================================================================
   /**
    * @brief 获取当前图表的交易品种
    * @return string - 品种代码（如 "EURUSD"，空字符串表示未绑定图表）
    */
   string            Symbol(void) const { return(ChartSymbol(m_chart_id)); }

   /**
    * @brief 获取当前图表的时间周期
    * @return ENUM_TIMEFRAMES - 时间周期枚举值（如 PERIOD_H1=1小时，WRONG_VALUE 表示未绑定图表）
    */
   ENUM_TIMEFRAMES   Period(void) const { return(ChartPeriod(m_chart_id)); }

   /**
    * @brief 强制刷新图表（立即更新图表显示，如修改属性后触发重绘）
    */
   void              Redraw(void) const { ChartRedraw(m_chart_id); }

   /**
    * @brief 获取图表的整数类型属性（底层API封装，支持所有枚举定义的整数属性）
    * @param prop_id [in] 属性ID（ENUM_CHART_PROPERTY_INTEGER 枚举值，如 CHART_MODE=显示模式）
    * @param sub_window [in] 子窗口编号（0=主窗口，≥1=指标子窗口，部分属性无需指定子窗口）
    * @return long - 属性值（0 表示未绑定图表或属性无效）
    */
   long              GetInteger(const ENUM_CHART_PROPERTY_INTEGER prop_id,const int sub_window=0) const;

   /**
    * @brief 获取图表的整数类型属性（通过引用返回，支持错误检测）
    * @param prop_id [in] 属性ID（ENUM_CHART_PROPERTY_INTEGER 枚举值）
    * @param sub_window [in] 子窗口编号
    * @param value [out] 输出参数，存储获取到的属性值
    * @return bool - 操作结果：true 表示获取成功，false 表示失败（未绑定图表或属性无效）
    */
   bool              GetInteger(const ENUM_CHART_PROPERTY_INTEGER prop_id,const int sub_window,long &value) const;

   /**
    * @brief 设置图表的整数类型属性（底层API封装，支持所有枚举定义的整数属性）
    * @param prop_id [in] 属性ID（ENUM_CHART_PROPERTY_INTEGER 枚举值）
    * @param value [in] 目标属性值
    * @return bool - 操作结果：true 表示设置成功，false 表示失败（未绑定图表或属性无效）
    */
   bool              SetInteger(const ENUM_CHART_PROPERTY_INTEGER prop_id,const long value) const;

   /**
    * @brief 获取图表的浮点类型属性（底层API封装，支持所有枚举定义的浮点属性）
    * @param prop_id [in] 属性ID（ENUM_CHART_PROPERTY_DOUBLE 枚举值，如 CHART_FIXED_MAX=价格轴最大值）
    * @param sub_window [in] 子窗口编号
    * @return double - 属性值（EMPTY_VALUE 表示未绑定图表或属性无效）
    */
   double            GetDouble(const ENUM_CHART_PROPERTY_DOUBLE prop_id,const int sub_window=0) const;

   /**
    * @brief 获取图表的浮点类型属性（通过引用返回，支持错误检测）
    * @param prop_id [in] 属性ID（ENUM_CHART_PROPERTY_DOUBLE 枚举值）
    * @param sub_window [in] 子窗口编号
    * @param value [out] 输出参数，存储获取到的属性值
    * @return bool - 操作结果：true 表示获取成功，false 表示失败（未绑定图表或属性无效）
    */
   bool              GetDouble(const ENUM_CHART_PROPERTY_DOUBLE prop_id,const int sub_window,double &value) const;

   /**
    * @brief 设置图表的浮点类型属性（底层API封装，支持所有枚举定义的浮点属性）
    * @param prop_id [in] 属性ID（ENUM_CHART_PROPERTY_DOUBLE 枚举值）
    * @param value [in] 目标属性值
    * @return bool - 操作结果：true 表示设置成功，false 表示失败（未绑定图表或属性无效）
    */
   bool              SetDouble(const ENUM_CHART_PROPERTY_DOUBLE prop_id,const double value) const;

   /**
    * @brief 获取图表的字符串类型属性（底层API封装，支持所有枚举定义的字符串属性）
    * @param prop_id [in] 属性ID（ENUM_CHART_PROPERTY_STRING 枚举值，如 CHART_TEMPLATE=图表模板名称）
    * @return string - 属性值（空字符串表示未绑定图表或属性无效）
    */
   string            GetString(const ENUM_CHART_PROPERTY_STRING prop_id) const;

   /**
    * @brief 获取图表的字符串类型属性（通过引用返回，支持错误检测）
    * @param prop_id [in] 属性ID（ENUM_CHART_PROPERTY_STRING 枚举值）
    * @param value [out] 输出参数，存储获取到的属性值
    * @return bool - 操作结果：true 表示获取成功，false 表示失败（未绑定图表或属性无效）
    */
   bool              GetString(const ENUM_CHART_PROPERTY_STRING prop_id,string &value) const;

   /**
    * @brief 设置图表的字符串类型属性（底层API封装，支持所有枚举定义的字符串属性）
    * @param prop_id [in] 属性ID（ENUM_CHART_PROPERTY_STRING 枚举值）
    * @param value [in] 目标属性值
    * @return bool - 操作结果：true 表示设置成功，false 表示失败（未绑定图表或属性无效）
    */
   bool              SetString(const ENUM_CHART_PROPERTY_STRING prop_id,const string value) const;

   /**
    * @brief 同时设置图表的交易品种和时间周期
    * @param symbol [in] 目标品种代码（如 "GBPUSD"）
    * @param period [in] 目标时间周期（ENUM_TIMEFRAMES 枚举值）
    * @return bool - 操作结果：true 表示设置成功，false 表示失败（未绑定图表或品种/周期无效）
    */
   bool              SetSymbolPeriod(const string symbol,const ENUM_TIMEFRAMES period) const;

   /**
    * @brief 应用图表模板（加载预定义的图表配置，如颜色、指标、对象等）
    * @param filename [in] 模板文件路径（相对路径，如 "Templates/MyTemplate.tpl"）
    * @return bool - 操作结果：true 表示应用成功，false 表示失败（未绑定图表或文件不存在）
    */
   bool              ApplyTemplate(const string filename) const;

   /**
    * @brief 对图表进行截图并保存为文件
    * @param filename [in] 截图文件路径（如 "Screenshots/Chart20240101.png"，支持 PNG/JPG 格式）
    * @param width [in] 截图宽度（像素，0 表示使用图表实际宽度）
    * @param height [in] 截图高度（像素，0 表示使用图表实际高度）
    * @param align_mode [in] 对齐模式（ENUM_ALIGN_MODE 枚举值，如 ALIGN_RIGHT=右对齐，控制截图区域）
    * @return bool - 操作结果：true 表示截图成功，false 表示失败（未绑定图表或文件路径无效）
    */
   bool              ScreenShot(const string filename,const int width,const int height,
                                const ENUM_ALIGN_MODE align_mode=ALIGN_RIGHT) const;

   /**
    * @brief 获取鼠标拖放操作对应的子窗口编号（拖放对象时触发）
    * @return int - 子窗口编号（0=主窗口，≥1=指标子窗口，0 表示未触发拖放或获取失败）
    */
   int               WindowOnDropped(void) const;

   /**
    * @brief 获取鼠标拖放操作对应的价格（拖放对象时触发）
    * @return double - 拖放位置的价格（EMPTY_VALUE 表示未触发拖放或获取失败）
    */
   double            PriceOnDropped(void) const;

   /**
    * @brief 获取鼠标拖放操作对应的时间（拖放对象时触发）
    * @return datetime - 拖放位置的时间（0 表示未触发拖放或获取失败）
    */
   datetime          TimeOnDropped(void) const;

   /**
    * @brief 获取鼠标拖放操作对应的 X 坐标（像素，相对于图表窗口）
    * @return int - X 坐标（像素，0 表示未触发拖放或获取失败）
    */
   int               XOnDropped(void) const;

   /**
    * @brief 获取鼠标拖放操作对应的 Y 坐标（像素，相对于图表窗口）
    * @return int - Y 坐标（像素，0 表示未触发拖放或获取失败）
    */
   int               YOnDropped(void) const;

   //================================================================
   // 模块7：图表指标管理（添加、删除、查询指标）
   //================================================================
   /**
    * @brief 向指定子窗口添加技术指标
    * @param subwin [in] 目标子窗口编号（0=主窗口，≥1=新建/已有指标子窗口）
    * @param handle [in] 指标句柄（通过 iMA/iRSI 等指标创建函数获取的句柄）
    * @return bool - 操作结果：true 表示添加成功，false 表示失败（未绑定图表或句柄无效）
    */
   bool              IndicatorAdd(const int subwin,const int handle) const;

   /**
    * @brief 从指定子窗口删除技术指标
    * @param subwin [in] 子窗口编号（0=主窗口，≥1=指标子窗口）
    * @param name [in] 指标名称（图表上显示的指标名称，需与添加时一致）
    * @return bool - 操作结果：true 表示删除成功，false 表示失败（未绑定图表或指标不存在）
    */
   bool              IndicatorDelete(const int subwin,const string name) const;

   /**
    * @brief 获取指定子窗口中的指标总数
    * @param subwin [in] 子窗口编号（0=主窗口，≥1=指标子窗口）
    * @return int - 指标数量（0 表示未绑定图表、子窗口无效或无指标）
    */
   int               IndicatorsTotal(const int subwin) const;

   /**
    * @brief 获取指定子窗口中指定索引的指标名称
    * @param subwin [in] 子窗口编号
    * @param index [in] 指标索引（从 0 开始，范围 0~IndicatorsTotal(subwin)-1）
    * @return string - 指标名称（空字符串表示未绑定图表、子窗口无效或索引超出范围）
    */
   string            IndicatorName(const int subwin,const int index) const;

   //================================================================
   // 模块8：图表配置序列化（保存/加载图表属性配置）
   //================================================================
   /**
    * @brief 将当前图表的配置参数保存到文件
    * @param file_handle [in] 文件句柄（需提前以 FILE_WRITE 模式打开，如通过 FileOpen 函数创建）
    * @return bool - 操作结果：true 表示保存成功，false 表示失败（文件无效或未绑定图表）
    * @note 保存内容包括：图表品种、周期、显示模式、缩放、颜色、显示元素开关等核心配置
    */
   virtual bool      Save(const int file_handle);

   /**
    * @brief 从文件加载图表配置参数并应用到当前绑定的图表
    * @param file_handle [in] 文件句柄（需提前以 FILE_READ 模式打开）
    * @return bool - 操作结果：true 表示加载成功，false 表示失败（文件无效或未绑定图表）
    */
   virtual bool      Load(const int file_handle);

   //================================================================
   // 模块9：对象类型标识（重写父类方法，标识 CChart 类类型）
   //================================================================
   /**
    * @brief 获取当前对象的类型标识（用于区分不同对象类）
    * @return int - 类型标识（固定返回 0x1111，为 CChart 类的唯一标识）
    */
   virtual int       Type(void) const { return(0x1111); }
  };
//+------------------------------------------------------------------+